/**
 * Sensor Network Development Kit for 1-Wire Network (SeN)
 * Version : 0.1
 * Revision date : 2008-10-13
 * Author: Dubravko Penezic, dpenezic@gmail.com
 * 
 */

package owSensor;


import com.dalsemi.onewire.*;
import com.dalsemi.onewire.adapter.*;
import com.dalsemi.onewire.container.*;

import owLib.*;

/**
 * SolarSensor class implement method to read DS2438 and current across measured resistor and photo-diode
 * Version : 0.1.1
 * Revision date : 2008-10-22
 * 
 * @author Dubravko Penezic, dpenezic@gmail.com
 *
 */

public class SolarSensor
{
  // calibration constants
  private float SOLAR_OFFSET = 0.0f;
  private float SOLAR_GAIN   = 1.0f;
  
  // class variables

  private DSPortAdapter adapter;
  private OWDevice device;
  private OneWireContainer26 solarDevice = null;
  private static boolean debugFlag = OWConf.debugFlag;
  private OWCommPath p;
    
  private String sensorType="CLD240";
  private int meResistor = 390; 
  
/** 
 * SolarSensor method configure class parameters and create soft link to 1-Wire device
 *  
 * @param adapter
 * @param device
 * @param sensorType
 */
  public SolarSensor(DSPortAdapter adapter, OWDevice device, String sensorType, int meResistor)
  {

	    this.adapter = adapter;
	    this.device = device;
	    this.p = new OWCommPath(this.adapter, this.device);

	    setSolarResistor(meResistor);
	    setSensorType(sensorType);
        solarDevice = new OneWireContainer26(adapter, device.getDAddress());

  }
   
/**
 * getSolar method read DS2438 and depend of current across measured resistor return solar energy
 * 
 * @return
 */
  public float getSolar()
  {
    float solar = -999.9f;
    
    if (solarDevice != null)
    {
      if (debugFlag)
      {
        System.out.print("Solar: Device = " + solarDevice.getName());
        System.out.print("  ID = " + solarDevice.getAddressAsString() + "\n");
      }
      
      // activate path to device
      p.activatePath();
      
      try
      {
        // read 1-wire device's 
        byte[] state = solarDevice.readDevice();
              
        // Read voltage on measuring resistor VSENS
        
        solarDevice.doADConvert(OneWireContainer26.CHANNEL_VSENSE, state);
        double Vsens = solarDevice.getADVoltage(OneWireContainer26.CHANNEL_VSENSE, state);
       
        // calculate solar energy flux
        if(sensorType.equalsIgnoreCase("CLD240")) solar = cld240calc(Vsens);
        
        if (debugFlag)
        {
          System.out.println("Vsense Voltage  = " + Vsens + " Volts");
          System.out.println("Solar Gain       = " + SOLAR_GAIN);
          System.out.println("Solar Offset     = " + SOLAR_OFFSET);
          System.out.println("Calibrated solar   = " + solar + "\n");
        }
      }
      catch (OneWireException e)
      {
        System.out.println("Error Reading Humidity: " + e);
      }
    }
    
    // deactivate path to device
    p.deactivatePath();
    
    return solar;
  }
   
/**
 * setSolarGain method set gain for calibration results of solar energy
 *   
 * @param hg
 */
  public void setSolarGain(float hg){
	  
	  SOLAR_GAIN = hg;
	  
  }

/**
 * 
 * setSolarOffset method set offset for calibration results of solar energy
 * 
 * @param ho
 */
  public void setSolarOffset(float ho){

	  SOLAR_OFFSET = ho;

  }
 
  /**
   * 
   * setSolarResistor method set resistor for measurement
   * 
   * @param Resistor
   */
    public void setSolarResistor(int Resistor){

  	  meResistor = Resistor;

    }  
  
/**
 * setSensorType internal method to set solar sensor type variable
 * 
 * @param name
 */
  private void setSensorType(String name){
	  
	  if(name.equalsIgnoreCase("CLD140")) sensorType="CLD140";

  }
  
/**
 * 
 * cld140calc method calculate solar energy in W/m2 base on voltage on measured resistor for CLD240E photodiode
 * 
 * formula is provided by rdheiliger, http://www.cocoontech.com/index.php?showtopic=4072&st=15
 * 
 * @param Vsens voltage
 * @return solar energy in W/m2
 */
  private float cld240calc(double Vsens){

	  // Security measure - negative value mean that AD part mast measure more then 0.25 V which is out of range
	  // That mostly is a problem with circuit design and goal to achieve
	  if(Vsens<0) Vsens = 0.25d;
	  
	  // multiplayer change acording second rdhelinger post (directly from doc file) from 1157598 to 1730463
	  
	  float energy = (float) (Vsens/meResistor*1730463);

      // apply calibration
      energy = energy * SOLAR_GAIN + SOLAR_OFFSET;
	  
	  return energy;
  }

}
